﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using CacheProvider;
using CacheBehaviorExtension;
using CacheProviderEntities;

namespace DemoWcfService
{
    public class TestWcfService : ITestWcfService
    {
        private const string DbName = "AdventureWorks";
        private const string connectionString = @"Data Source=SRVBLRCAF01\MSBLRTCTD01;Integrated Security=true;" +
                    "Initial Catalog=AdventureWorks;";

        #region ITestWcfService Members


        public List<ProductInfo> GetProductInfo_ExplicitCaching()
        {
            const string cacheKey = "Products";
            var products = CacheBroker.Get<List<ProductInfo>>(cacheKey);
            if (products == null)
            {
                using (var context = new AdventureworksDataContext(GetConnectionString()))
                {
                    products = GetProductDetails(context);

                    var dependencyCommand = from product in context.Products
                                            select product;

                    var dependencyInfo = new DependencyInfo(CacheDependencyTypes.SQLDependency)
                                                           {
                                                               DBConnectionString = GetConnectionString(),
                                                               DBName = "AdventureWorks",
                                                               IsSQLSelectQueryBased = true
                                                           };

                    dependencyInfo.SelectQueries.Add(context.GetCommand(dependencyCommand).CommandText);

                    CacheBroker.Put(cacheKey, products, dependencyInfo);
                }
            }

            return products;
        }

        [CachingOperationBehavior(Key = "ProductInfo",
                                  DependencyDbConnectionString = connectionString,//DependencyDbConnectionString=ConfigurationManager.ConnectionStrings[""].ToString(),
                                  DependencyDbName = DbName,
                                  DependencySqlQuery = "SELECT P.[ProductID], P.[Name], P.[ProductNumber], P.[MakeFlag], P.[FinishedGoodsFlag], P.[Color], P.[SafetyStockLevel], P.[ReorderPoint], P.[StandardCost], P.[ListPrice], P.[Size], P.[SizeUnitMeasureCode], P.[WeightUnitMeasureCode], P.[Weight], P.[DaysToManufacture], P.[ProductLine], P.[Class], P.[Style], P.[ProductSubcategoryID], P.[ProductModelID], P.[SellStartDate], P.[SellEndDate], P.[DiscontinuedDate], P.[ModifiedDate] FROM [Production].[Product] AS P",
                                  DependencyType = CacheDependencyTypes.SQLDependency
                                 )]
        public List<ProductInfo> GetProductInfo_CachedThroughBehavior()
        {
            using (var context = new AdventureworksDataContext(GetConnectionString()))
            {
                return GetProductDetails(context);
            }
        }


        #endregion


        private static List<ProductInfo> GetProductDetails(AdventureworksDataContext context)
        {
            var productInfoQuery = from product in context.Products
                                   join cat in context.ProductSubcategories
                                   on product.ProductSubcategoryID equals cat.ProductSubcategoryID
                                   join sizeUnit in context.UnitMeasures
                                   on product.SizeUnitMeasureCode equals sizeUnit.UnitMeasureCode into su
                                   from availableSizeUnit in su.DefaultIfEmpty() //signifies LEFT OUTER JOIN
                                   join weightUnit in context.UnitMeasures on product.WeightUnitMeasureCode equals weightUnit.UnitMeasureCode into wu
                                   from availableWeightUnit in wu.DefaultIfEmpty() //signifies LEFT OUTER JOIN
                                   select new
                                   {
                                       ProductName = product.Name,
                                       ProductCategory = cat.Name,
                                       Price = product.ListPrice,
                                       Size = product.Size,
                                       SizeUnit = availableSizeUnit.Name,
                                       WeightUnit = availableWeightUnit.Name,
                                       Weight = product.Weight
                                   };

            var productsInfo = from productData in productInfoQuery
                               select new ProductInfo
                               {
                                   ProductName = productData.ProductName,
                                   ProductCategory = productData.ProductCategory,
                                   Price = productData.Price,
                                   Size = productData.Size,
                                   SizeUnit = productData.SizeUnit,
                                   WeightUnit = productData.WeightUnit,
                                   Weight = productData.Weight
                               };

            List<ProductInfo> products = productsInfo.ToList();
            return products;
        }

        private static string GetConnectionString()
        {
            if (Environment.MachineName.Equals("IN8202039D"))
                return @"Data Source=SRVBLRCAF01\MSBLRTCTD01;Integrated Security=true;" +
                  "Initial Catalog=AdventureWorks;";

            return @"Data Source=RAHUL-PC\SQL2008EXPRESS;Integrated Security=true;" +
              "Initial Catalog=AdventureWorks;";
        }
    }
}
